﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using YJKSparseDistance.ModelLayer;
using YJKSparseDistance.Properties;
using YJKSparseDistance.ViewLayer;
using YJKRoomInspection.ProgramArchitecture;
using YJKRoomInspection.Utiltiy;
using YArchitech.Controls;
using YJKRevitBase.WinForm.BackGroundProgressBar;
using YJKInspectModelFunc;
using YJKInspectModelFunc.ModelLayer;

namespace YJKSparseDistance.ControlLayer
{
	public class EvacuationDistanceArch : IFlowYJKRoomInspection
	{
		public static RulePacker UesRulePacker
		{
			get
			{
				return EvacuationDistanceArch.m_uesRulePacker;
			}
			private set
			{
				EvacuationDistanceArch.m_uesRulePacker = value;
			}
		}

		public EvacuationDistanceArch()
		{
			Document document = TempleCmd.ExternalCommandData.Application.ActiveUIDocument.Document;
			List<Level> lstSelectLevel = TempleCmd.LstSelectLevel;
			this.m_doc = document;
			this.m_lstLevel = lstSelectLevel;
		}

		public void CheckMethod()
		{
			bool flag = this.DoCheck(this.m_doc, this.m_lstLevel);
			if (this.m_useForm != null && !flag && this.m_bIfCalculateSucessed)
			{
				if (this.m_nAreaCount != 0)
				{
					new LoopMangerNoneSwitch_EvacuationDistance(TempleCmd.ExternalCommandData.Application.ActiveUIDocument, this.m_useForm, null, null, null).DoLoopWork();
					return;
				}
				YJKMessageBox.Show(Resources.Str_Message_NoneArea);
				return;
			}
			else
			{
				if (this.m_bIfCalculateSucessed)
				{
					YJKMessageBox.Show(Resources.Str_NoneError);
					return;
				}
				return;
			}
		}

		public static List<ICloseCurveAnalays> GetFrontRoomData(UIDocument useUiDoc, List<Level> inputLevels)
		{
			List<Element> lstInputElment = YJKRoomInspection.Utiltiy.Utility.FilterElementFormDoc(useUiDoc, inputLevels);
			List<Phase> list = new List<Phase>();
			foreach (object obj in useUiDoc.Document.Phases)
			{
				Phase item = (Phase)obj;
				list.Add(item);
			}
			return CloseCurveAnalyser_EvacuationDistance.GetCloseCurveAnalysis(useUiDoc.Document, lstInputElment, inputLevels, list, true);
		}

		public bool DoCheck(Autodesk.Revit.DB.Document useDoc, List<Level> inputLevels)
		{
			EvacuationDistanceArch.UesRulePacker = null;
			EvacuationDistanceArch.UesRulePacker = EvacuationDistanceArch.GetRuleData(TempleCmd.RevitHandle);
			if (EvacuationDistanceArch.UesRulePacker == null)
			{
				return true;
			}
			ProgressBarManger progressBarManger = new ProgressBarManger(new BackWorkDelegate(this.DoChekBackWork));
			progressBarManger.ShowFormAndDoWork(TempleCmd.RevitHandle);
			return progressBarManger.IfManualAbsort;
		}

		public static RulePacker GetRuleData(IWin32Window inputRevitHandle)
		{
			string empty = string.Empty;
			BuildingTypeSelectForm buildingTypeSelectForm = new BuildingTypeSelectForm(YJKInspectModelFunc.Utility.GetAppRootPath() + "\\Data\\");
			if (buildingTypeSelectForm.UseDocument == null)
			{
				YJKMessageBox.Show(Resources.Str_MessageNoneXml);
				return null;
			}
			buildingTypeSelectForm.ShowDialog(inputRevitHandle);
			return buildingTypeSelectForm.ReturnValue;
		}

		private void DoChekBackWork()
		{
			Document doc = this.m_doc;
			List<Level> lstLevel = this.m_lstLevel;
			List<ICloseCurveAnalays> frontRoomData = EvacuationDistanceArch.GetFrontRoomData(TempleCmd.ExternalCommandData.Application.ActiveUIDocument, lstLevel);
			List<Phase> list = new List<Phase>();
			foreach (object obj in doc.Phases)
			{
				Phase item = (Phase)obj;
				list.Add(item);
			}
			List<AreaPacker_EvacuationDistance> areas = new AreaGeter().GetAreas(doc, lstLevel, frontRoomData, list);
			this.m_nAreaCount = areas.Count;
			List<AreaCheckResultPacker> list2 = new List<AreaCheckResultPacker>();
			foreach (AreaPacker_EvacuationDistance areaPacker_EvacuationDistance in areas)
			{
				AreaCalculateManger areaCalculateManger = new AreaCalculateManger(areaPacker_EvacuationDistance);
				List<string> allValues;
				Entity entity;
				bool flag = InsetDataUtility.TryGetAddedValue(Resources.Str_GuidForEvacuation, areaPacker_EvacuationDistance.ThisElement as Area, out allValues, out entity);
				AreaCheckResultPacker result = areaCalculateManger.GetResult();
				List<ResultBean> list3 = new List<ResultBean>();
				foreach (ResultBean resultBean in result.LstErrorResult)
				{
					if (!flag || !YJKSparseDistance.Utility.IfResultTrusted(resultBean, allValues))
					{
						list3.Add(resultBean);
					}
				}
				if (list3.Count > 0)
				{
					list2.Add(areaCalculateManger.GetResult());
				}
			}
			if (list2.Count != 0)
			{
				new List<List<AreaCheckResultPacker>>();
				ResultForm useForm = new ResultForm(EvacuationDistanceArch.GroupResult(list2), Resources.Str_CmdName_RunWay, TempleCmd.RevitHandle, TempleCmd.ExternalCommandData.Application.ActiveUIDocument, null);
				this.m_useForm = useForm;
			}
			this.m_bIfCalculateSucessed = true;
		}

		public static List<List<AreaCheckResultPacker>> GroupResult(List<AreaCheckResultPacker> input)
		{
			List<List<AreaCheckResultPacker>> list = new List<List<AreaCheckResultPacker>>();
			foreach (IEnumerable<AreaCheckResultPacker> enumerable in from k in input
			group k by k.ThisLevel.Id.IntegerValue)
			{
				list.Add(new List<AreaCheckResultPacker>());
				foreach (AreaCheckResultPacker item in enumerable)
				{
					list[list.Count - 1].Add(item);
				}
			}
			return list;
		}

		private ResultForm m_useForm;

		private Document m_doc;

		private List<Level> m_lstLevel;

		private int m_nAreaCount;

		private static RulePacker m_uesRulePacker;

		private bool m_bIfCalculateSucessed;
	}
}
